
#ifndef __ENCMESSAGE_H
#define __ENCMESSAGE_H

#include <vector>
#include <stdarg.h>
#include <apr_pools.h>
#include <apr_tables.h>
#include "../aprtools/APRTable.h"

/** Encapsulated message. This is a container for the parts of the
 * messages to and from the broker. This low level interface gives
 * access to each of the elements of the message, and automates much
 * of the processing to do with managing the message headers and body
 * of content. */
class EncMessage
{
   public:
      EncMessage(apr_pool_t *imp);
      EncMessage(const EncMessage &other);
      EncMessage &operator=(const EncMessage &other);
      ~EncMessage();

      void replyTo(const EncMessage &imsg);
      void setRecipient(const char *iformat, ...);
      void setSender(const char *iformat, ...);
      void addTypeHeaderNOCRLF(const char *itype, const char *iprocessee);
      void addHeaderLineNOCRLF(const char *iformat, ...);
      int addPayloadString(const char *iformat, ...);
      int addVerbatimPayloadString(const char *istring);
      int addPayloadBuffer(const char *ibuffer, int ilength);
      int addPayloadTextFile(const char *iformat, ...);
      void forceNoSignature();
      void forceDestroySendingKey();

      void reset();

      void setWasSignedFlag();
      void parseHeaderStream(const char *stream);
      void generateHeaderTable();
      char *getHeaderStream() const;

      const char *getRecipient() const;
      const char *getSender() const;
      const char *getType() const;
      const char *getProcessee() const;
      const int getHowManyPayloads() const;
      const char *getPayload(int pnum) const;
      const int getPayloadLength(int pnum) const;
      const int isType(const char *ctype) const;
      const int isProcessee(const char *cprocessee) const;
      const int isPayloadCount(const int pcount) const;
      const int mustWeDestroySendingKey() const;
      const int guaranteedAuthentic() const;
      const int mustWeSign() const;

      apr_pool_t *getEncMessageAssociatedMemoryPool() const;
      const APRTable *getHeaderTable() const;
      APRTable *getAuxHeaderTable(int payload, const char *linesep, const char *keyvalsep, int *auxheaders) const;

      void print() const;
      int isBinary(const char *bindata, int length) const;
      void printHex(const char *bindata, int length) const;
   protected:
      void copy(const EncMessage &other);
      /** The parent memory pool. */
      apr_pool_t *highmp;
      /** The memory pool in use in this class, generated as a child
       * of #highmp. */
      apr_pool_t *mp;
      /** The intended recipient of the message. */
      const char *recipient;
      /** The receiving key for the message. */
      const char *recipientkey;
      /** The sender on whose behalf and with whose credentials the
       * message is sent. */
      const char *sender;
      /** The sending key for the message. */
      const char *senderkey;
      /** A table of headers, for easy processing. */
      APRTable *htable;
      /** A string that describes the type of operation encoded by the
       * message. */
      const char *messagetype;
      /** The object or actor that will be processed or modified by
       * the action of this message. */
      const char *processee;
      /** Vector of header strings for each parsed header. */
      std::vector<const char *> *headers;
      /** Vector of payloads for each parse payload stream. */
      std::vector<const char *> *payloads;
      /** Vector of lengths for each stream parsed from the encrypted
       * packet stream. */
      std::vector<unsigned int> *lengths;
      /** Whether we will sign this packet on the way out. */
      int willsign;
      /** Whether we found a signature for the packet on the way
       * in. */
      int issigned;
      /** Whether we should remove the identity that sent this packet
       * immediately after sending it. */
      int removesendingkey;
};

#endif
